package com.example.zhunongzonghe.controller;


import com.alibaba.fastjson2.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.zhunongzonghe.common.Result;
import com.example.zhunongzonghe.common.WebSocket;
import com.example.zhunongzonghe.config.AliReturnPay;
import com.example.zhunongzonghe.entity.ZnFarmhouse;
import com.example.zhunongzonghe.entity.ZnFarmhouseReserve;
import com.example.zhunongzonghe.entity.ZnOrder;
import com.example.zhunongzonghe.service.IZnFarmhouseReserveService;
import com.example.zhunongzonghe.service.IZnFarmhouseService;
import com.example.zhunongzonghe.service.IZnOrderService;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@RestController
@RequestMapping("/Alipay")
public class AliPayController {
    @Autowired
    private WebSocket webSocket;

    private static final String URL = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
    private static final String APP_ID = "9021000132693252";
    private static final String NatApp = "http://ps4uw8.natappfree.cc";
    //私钥
    private static final String APP_PRIVATE_KEY = "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCMwamI9JzCaYVgxTLQyxiK1xFp++kc6ml1B3nmVsXMi20Gr+5nopMRFWXrDmEWcVLnfjIPhtP1RU9zU9srk4UuT8AW/UQUXcRwAAOzLBg08dQrI5n/6MFYeLJoLscUhnF9mAM60Ry5vHMZoAX1kTT/4kx4Ni3hSAFs1RIEz7fUpnB1UCG7GwJsA1A0+d56qXO3Q3a2M/65T6a0g+zCVwbXV7DNjwOJ9X0Fs6dhXUuTUQlzOLa4kNrv5TRc2/sEcr66e0Yln3OJtVo4uCe30Ob/kOlv06r9WVQgzXelx4LOdPgBnBKok1KCnoarnhIet+YpMYeRGF1t5modftFtAYyjAgMBAAECggEAIgxSo0NwjAKUdfUdtq36MNOXbci2+fymJ934GcTRsgnkBKMYC0+jPZWsgrCGwbQF9uNq3qChswniDyawtJjJtYsrDySSjE6mTuVh/7xh2qTIyuqgvOujoXAIz/TIyWlAGL5lwZuF1FQGj6NK7b0DUgZ+svGAJaeSWK4t3qYUdMa0AcV8EQbQ503jMnaZaIVWS3cQhmUYLMDbxIrOikeBBKF1n/rOqFpo4pUNv/wn6NkpR8XqvCK3r/ia1SOoL6axgqetLKSY8Ijhc+E3Ts24xrEWVJ1vDgNIwE2092pWDNnbagz0+F+SZJeUEUpKzTbZRe9Gs8DWZnfc8iny7LAB+QKBgQDs6DGf5DdNm5cVYp6UuKuekqq1sRyMgOiTYZ8VR2V06b0XXO0edrhps9cDPEs8Ni+M7NJKeYTYeqBS/p2jdc1QgpwXGkCnF1+2QRgGorRLtCaZyWruqjqhnzEl7QduhYBSBs7nfYIbAg+082t/dJke47rx+GjJW0t4GwA3kEYh5wKBgQCYGbcMF+u7sQBd4+nEZxSSjOCEeOXMAfdJwOMlEl26GmRJziggOVj9/OgFOmdwKDIBDkDJ+HSCLjYn/TM6CHSL/X4R/QSiBdIIEynvs1EYeFN6G+BJjRInYO9hzbCaAa2jxNPerysS+NCxooVIiQ3UtdSvzgPi89affb2UBbvf5QKBgQDDfsRcnlXorAlb81rLfSzaGUvXzUSyyTmjTT6ar6UQekW4/s0Jg4ygZXB70gh/snNAxriuDmNKxL6CXmw1VGPOGUm3YsmRWR95ZXPvHdrMUeg8pdKhCkaB0r0a/+NPF8mRZt7cdlyj7uqJNwoxTkWBEQnW3VeTOcwoW5etQlgtZwKBgEh7YKars5PTCqizltAYi043Qjr+3gt1GGIWQGiHMxEfyJD/ZFHO4mDPJ8ZuCaMCFKo6H5fgBa2P1hECcWoDY37ewzhRSeboPSnJ8B8hZdDybl1vcVe7mV4YrJsACVuq1xOHFaw176Hv3ov4NenWHjgymnNZCrMZnjqNEk262cgdAoGBAOrRggubhmO6QAdkuFvxZTv+w6rRj/2cNVXjNvI1BxfyZ/1v3Mb37ogoEWLZyy2bpjkJsAsne2g9HStxnFzHk+IjpnwVF13SGQAYvjUKXlBATgaPUnrTTpMDx/gNty5d8nnj8Fr6/Ll6x8pFrl7XlSIUaC/5oE9CxHGpw6peb2Ji";
    //公钥
    private static final String ALIPAY_PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqI9xQFHzIUxz+t1dqW5flAZxr5bgaReyYPbU3lSBDXH6UgBAb4Un9xFF5y6n9lR5WEwGTxve8NKIQo10xbPk1f1WI7nSmZQZbKKkRrhQI5pi4rXKxDt5fuguYb3hKmKWTAK7q6Jegr1q38X5Wo6ImK0F4yR1kHv0iRPGJTtAY1aj5mwjXNpqXAfoG/jODgut/Ei7zG0JsEJzLsjCYstNMNj64dB3b8Z0QL2MXSpcR+VeS7Zx0qv5NPkJTZSfxPCO+GAdhyDJWM3qETH39gOGdYNodj63zdtTIzRS8mZ8zqUKMaiIyU1XiG8yNjoM+LEoCkXZDT2Lv8t1nM/oGmoyeQIDAQAB";
    private static final String FORMAT = "json";
    private static final String CHARSET = "UTF-8";
    // 验签加密方法
    private static final String SIGN_TYPE = "RSA2";
    @Autowired
    private IZnOrderService iZnOrderService;

    @Autowired
    private IZnFarmhouseReserveService znFarmhouseReserveService;
    @Autowired
    private IZnFarmhouseService iZnFarmhouseService;

    /**
     * 用户农产品订单退款
     * @param orderNumber
     * @return
     */
    @RequestMapping("/refund")
    public Result farmRefund(String orderNumber) throws AlipayApiException {
        ZnOrder znOrder = iZnOrderService.getOneOrder(orderNumber);
        AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", orderNumber);
        bizContent.put("refund_amount", znOrder.getTotalPrice());
        bizContent.put("out_request_no", "HZ01RF001");
        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()){
            znOrder.setPayStatus(3);
            iZnOrderService.updateById(znOrder);
            return new Result(true,"成功",200);
        }else {
            return new Result(false,"失败",400);
        }
    }

    /**
     * 农家乐退款
     * @param reserveNumber
     * @return
     * @throws AlipayApiException
     */
    @RequestMapping("/refundHouse")
    public Result HouseRefund(String reserveNumber) throws AlipayApiException {
        LambdaQueryWrapper<ZnFarmhouseReserve> queryWrapper =new LambdaQueryWrapper<>();
        queryWrapper.eq(ZnFarmhouseReserve::getReserveNumber,reserveNumber);
        ZnFarmhouseReserve reserve = znFarmhouseReserveService.getOne(queryWrapper);
        AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", reserveNumber);
        bizContent.put("refund_amount", reserve.getTotalPrice());
        bizContent.put("out_request_no", "HZ01RF001");
        request.setBizContent(bizContent.toString());
        AlipayTradeRefundResponse response = alipayClient.execute(request);
        if (response.isSuccess()){
            reserve.setPayStatus(2);
            reserve.setReserveStatus(3);
            znFarmhouseReserveService.updateById(reserve);
            return new Result(true,"成功",200);
        }else {
            return new Result(false,"失败",400);
        }
    }

    /**
     * 农产品支付接口
     * @param orderNumber
     * @return
     * @throws AlipayApiException
     */
    @ApiOperation(value = "支付宝支付 沙箱环境")
    @PostMapping("/sandboxPay")
    public Result pay(String orderNumber) throws AlipayApiException {
        LambdaQueryWrapper<ZnOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ZnOrder::getOrderNumber, orderNumber);
        ZnOrder znOrder = iZnOrderService.getOne(wrapper);
        AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(NatApp+"/Alipay/call");
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", znOrder.getOrderNumber());
        bizContent.put("total_amount", znOrder.getTotalPrice());
        bizContent.put("subject", "农产品交易");
        request.setBizContent(bizContent.toString());
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        // 返回支付宝支付网址，用于生成二维码
        if (response.isSuccess()) {
            String qr = response.getQrCode();
            return new Result(true,"成功",200,qr);
        } else {
            return new Result(false, "失败", 400);
        }
    }

    @ApiOperation(value = "支付宝支付 异步通知")
    @PostMapping("/call")
    public void call(HttpServletRequest request, HttpServletResponse response, AliReturnPay aliReturnPay) throws IOException, AlipayApiException {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //调用SDK验证签名
        //公钥验签示例代码
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
        if (signVerified) {
            LambdaQueryWrapper<ZnOrder> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ZnOrder::getOrderNumber, params.get("out_trade_no"));
            ZnOrder znOrder = iZnOrderService.getOne(wrapper);
            znOrder.setPayStatus(1);
            iZnOrderService.updateById(znOrder);
            // 通知返回的数据会封装到 AliReturnPay 类中
            response.setContentType("type=text/html;charset=UTF-8");
            if (("TRADE_SUCCESS").equals(aliReturnPay.getTrade_status())){
                // 向前端发送一条支付成功的通知
                webSocket.sendMessage("true");
            }
        }
    }


    /**
     * 农家乐预定订单支付接口
     * @param reserveNumber
     * @return
     * @throws AlipayApiException
     */
    @ApiOperation(value = "支付宝支付 沙箱环境")
    @PostMapping("/reservePay")
    public Result HousePay(String reserveNumber) throws AlipayApiException {
        LambdaQueryWrapper<ZnFarmhouseReserve> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ZnFarmhouseReserve::getReserveNumber, reserveNumber);
        ZnFarmhouseReserve znFarmhouseReserve = znFarmhouseReserveService.getOne(wrapper);
        LambdaQueryWrapper<ZnFarmhouse> FarmhouseWrapper = new LambdaQueryWrapper<>();
        FarmhouseWrapper.eq(ZnFarmhouse::getHouseId,znFarmhouseReserve.getHouseId());
        ZnFarmhouse znFarmhouse = iZnFarmhouseService.getOne(FarmhouseWrapper);
        AlipayClient alipayClient = new DefaultAlipayClient(URL, APP_ID, APP_PRIVATE_KEY, FORMAT, CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE);
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(NatApp+"/Alipay/reserveNotify");
        JSONObject bizContent = new JSONObject();
        bizContent.put("out_trade_no", znFarmhouseReserve.getReserveNumber());
        bizContent.put("total_amount", znFarmhouseReserve.getTotalPrice());
        bizContent.put("subject", znFarmhouse.getHouseName());
        request.setBizContent(bizContent.toString());
        AlipayTradePrecreateResponse response = alipayClient.execute(request);
        // 返回支付宝支付网址，用于生成二维码
        if (response.isSuccess()) {
            String qr = response.getQrCode();
            return new Result(true, "成功", 200, qr);
        } else {
            return new Result(false, "失败", 400);
        }
    }

    @ApiOperation(value = "支付宝支付 异步通知")
    @PostMapping("/reserveNotify")
    public void reserveNotify(HttpServletRequest request, HttpServletResponse response, AliReturnPay aliReturnPay) throws AlipayApiException {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        //调用SDK验证签名
        //公钥验签示例代码
        boolean signVerified = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE);
        if (signVerified) {
            LambdaQueryWrapper<ZnFarmhouseReserve> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(ZnFarmhouseReserve::getReserveNumber, params.get("out_trade_no"));
            ZnFarmhouseReserve znFarmhouseReserve = znFarmhouseReserveService.getOne(wrapper);
            znFarmhouseReserve.setPayStatus(1);
            znFarmhouseReserve.setPayTime(LocalDateTime.now());
            znFarmhouseReserveService.updateById(znFarmhouseReserve);
            // 通知返回的数据会封装到 AliReturnPay 类中
            response.setContentType("type=text/html;charset=UTF-8");
            if (("TRADE_SUCCESS").equals(aliReturnPay.getTrade_status())) {
                // 向前端发送一条支付成功的通知
                webSocket.sendMessage("true");
            }else if (("TRADE_FINISHED").equals(aliReturnPay.getTrade_status())){
                webSocket.sendMessage("false");
            }
        }
    }
}
